
Prepared Statement(프리페어드 스테이트먼트)는 데이터베이스에 보낼 SQL 문을 미리 준비(컴파일/파싱)해 두고, 실행 시에는 값(파라미터)만 바인딩해서 사용하는 방식입니다. 즉 SQL 구문과 데이터(값)를 분리해서 다루는 방법입니다. 주요 특징과 동작 방식 - 플레이스홀더 사용: SQL에 ? 또는 :name 같은 자리표시자를 넣고, 실행할 때 실제 값을 바인딩합니다. 예: SELECT * FROM users WHERE id = ? 또는 SELECT * FROM users WHERE email = :email - 준비(prepare): DB에 SQL을 보내 파싱·검사·실행계획을 생성(또는 준비)함. - 바인딩(bind): 실행 시점에 자리표시자에 실제 값을 전달. - 실행(execute): 바인딩된 값으로 쿼리를 실행하고 결과를 가져옴. - 종료(close): 필요 시 준비된 스테이트먼트를 닫아 리소스 해제. 장점 - 보안(주요): SQL 코드와 데이터가 분리되므로 SQL 인젝션 공격을 효과적으로 방어합니다. 전달된 값은 데이터로 취급되어 쿼리 구조를 변경할 수 없습니다. - 성능: 동일한 쿼리를 여러 번 실행하면 파싱·최적화 비용을 줄일 수 있습니다(서버 측에서 실행 계획 재사용). 대량 삽입·반복 실행에 유리합니다. - 가독성·유지보수: 값 바인딩 방식으로 코드가 깔끔해지고 파라미터 처리 일관성이 좋아집니다. 제한 및 주의사항 - 테이블명·컬럼명 같은 식별자는 파라미터로 대체할 수 없으므로 동적으로 조합할 때는 별도 처리(검증된 화이트리스트 등)가 필요합니다. - 한 번만 실행되는 단순 쿼리에서는 준비 오버헤드로 인해 성능 이점이 없을 수 있습니다. - 일부 드라이버는 클라이언트 측에서 에뮬레이션(실제로는 파라미터를 쿼리에 안전하게 삽입)하기도 하고, 일부 DB는 서버 측 준비를 지원합니다. 동작 방식에 따라 효과가 달라질 수 있습니다. 실무 예시(의사코드) - 준비: stmt = db.prepare("INSERT INTO products(name, price) VALUES (?, ?)") - 바인딩+실행: stmt.execute("사과", 1000) - 재실행: stmt.execute("배", 1200) - 종료: stmt.close() 주요 사용처: JDBC, PDO, psycopg2, MySQLi 등 대부분의 DB 드라이버/라이브러리에서 지원됩니다.